package com.sakura.probe.config.shiro;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.sakura.probe.common.util.JwtTokenUtil;
import com.sakura.probe.nosql.redis.RedisKey;
import com.sakura.probe.nosql.redis.RedisService;
import com.sakura.probe.pojo.JwtToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author Sakura
 */
@Slf4j
public class PersonInfoRealm extends AuthorizingRealm {
    @Autowired
    private RedisService service;

    @Override
    public boolean supports(AuthenticationToken token){
        return token instanceof JwtToken;
    }

    /**用户授权*/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("用户授权中");
        //获取当前登录的用户信息
        String username = JwtTokenUtil.getUsernameFromToken(principalCollection.toString());
        JSONObject person = JSONUtil.parseObj(service.get(RedisKey.getPersonInfo() + username));
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //设置用户角色
        if (null != person.get("role")){
            info.addRole(String.valueOf(person.get("role")));
        }
        return info;
    }

    /**用户认证*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("用户身份认证中......");
        //这里的token是从JwtFilter的executeLogin()中传递过来的
        String token = (String) authenticationToken.getCredentials();
        //从token中获取用户登录的账号(即用户名)
        String username = JwtTokenUtil.getUsernameFromToken(token);
        //从redis中根据账号获取对应的密码
        //JSONObject person = JSONUtil.parseObj(service.get("PERSONINFO" + username));
        if (null==username||0==username.length()||!JwtTokenUtil.verify(token,username)){
            log.error("token 认证失败");
            throw new AuthenticationException("token 认证失败");
        }
//        if (null == person){
//            log.error("账号或密码错误");
//            throw new AuthenticationException("账号或密码错误");
//        }
        log.info("账号:{}认证成功！", username);
        return new SimpleAuthenticationInfo(token, token, getName());
    }
}
